home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / Snippets / Toolbox / ShadingWinds / ShadingWinds.c next >
Encoding:
C/C++ Source or Header  |  1995-08-07  |  14.1 KB  |  638 lines  |  [TEXT/KAHL]

  1. /******************************************************************************************
  2.         ShadingWinds.c
  3.         
  4.     This little application includes code to allow you to detect whether or not the Shell
  5.     Window is "rolled up" by WindowShade.  How do you do this?  You check the window's 
  6.     contRgn.  If the contRgn is empty, then the window is shaded.  You'll note that the
  7.     grafPort is unchanged by WindowShade, so if you need to save window dimensions, you
  8.     can grab that information from the portRect.
  9.     
  10.     Written by Virginia (Ginny) McCulloh
  11.     Apple Developer Technical Support
  12.     March 1995, Cupertino, CA
  13.     Copyright 1995, Apple Computer, Inc.
  14.  
  15.     This runs under Think C 7.0.4 and MPW 3.3.1 with the Universal Headers.
  16. ******************************************************************************************/
  17.  
  18.  
  19. #include "ShadingWinds.h"
  20.  
  21. typedef struct {
  22.     Rect     windPort;
  23.     Point     windPosition;
  24. }WindDimAndPos;
  25.  
  26.  
  27. /*****     Prototypes      *****/
  28. void        main(void);
  29. void         initApp(void);
  30. Boolean        checkGestaltFeatures(void);
  31. Boolean     installAEHandlers();
  32. void         setUpMenus(void);
  33. void         setUpWindow(void);
  34. void         setUpMenus(void);
  35. void         doHighLevel(EventRecord *eventRec);
  36. void         doMousedown(EventRecord *eventRec);
  37. void         doKey(EventRecord *eventRec);
  38. void        doUpdate(EventRecord *eventRec);
  39. void         dispatch(long menuResult);
  40. void         doAppleCmds (short theItem);
  41. void         doFileCmds (short theItem);
  42. void         doTestCmds (short theItem);
  43. void         TestForWindowShade(void);
  44. void         HideShellWindow(void);
  45. void         RevealShellWindow(void);
  46.  
  47.  
  48. pascal OSErr    DoOpenAppAE(AppleEvent theAppleEvent, AppleEvent reply, long refCon);
  49. pascal OSErr    DoOpenDocAE(AppleEvent theAppleEvent, AppleEvent reply, long refCon);
  50. pascal OSErr    DoPrintDocAE(AppleEvent theAppleEvent, AppleEvent reply, long refCon);
  51. pascal OSErr    DoQuitAppAE(AppleEvent theAppleEvent, AppleEvent reply, long refCon);
  52.  
  53.  
  54. /*****  globals *****/
  55. Boolean            gQuitTheApp = false;        /* true = quit program */
  56. WindowPtr        gStatusWindow, gHiddenWindow;
  57. Boolean            gIsShellWindVisible = false;
  58. WindDimAndPos    myWindDimAndPos;
  59.  
  60. /*****    main() *****/
  61.  
  62. void main()
  63. {
  64.     short            sleepTime  =  60;
  65.     EventRecord        myEvent;
  66.  
  67.     
  68.     initApp();                                /* call initialization routine */
  69.     setUpMenus();
  70.     do
  71.     {
  72.         if (WaitNextEvent(everyEvent, &myEvent, sleepTime, NIL))
  73.             switch (myEvent.what)
  74.             {
  75.                 case mouseDown:
  76.                     doMousedown(&myEvent);
  77.                     break;
  78.                     
  79.                 case keyDown:
  80.                 case autoKey:
  81.                     doKey(&myEvent);
  82.                     break;
  83.  
  84.                 case kHighLevelEvent:
  85.                     doHighLevel(&myEvent);
  86.                     break;
  87.  
  88.                 case activateEvt:
  89.                     break;
  90.                 
  91.                 case updateEvt:
  92.                     doUpdate(&myEvent);
  93.                     break; 
  94.                 
  95.                 case diskEvt:
  96.                     break;
  97.             
  98.                 case osEvt:                /*  I don't really care yet. */
  99.                     break;
  100.             }
  101.     }  while (!gQuitTheApp);        
  102.     
  103. }                 /* end of main */
  104.  
  105.  
  106. /*****    initApp() *****/
  107.  
  108. void initApp()
  109. {
  110.     
  111.     /* Memory specific initializations. */
  112.     
  113.     MaxApplZone();                /* grow the heap to its maximum size */
  114.     MoreMasters();                   /* create more master pointers         */
  115.     MoreMasters();
  116.     MoreMasters();
  117.     MoreMasters();
  118.     MoreMasters();
  119.  
  120.     /* Initializing the ROM Managers */
  121.     
  122.     InitGraf((Ptr) &qd.thePort);
  123.     InitFonts();
  124.     InitWindows();
  125.     InitMenus();
  126.     FlushEvents(everyEvent,0);
  127.     TEInit();
  128.     InitDialogs(NIL);
  129.     InitCursor();
  130.     
  131.     if (!checkGestaltFeatures())
  132.         ExitToShell();
  133.     
  134.     /* Install the required Apple Event Handlers */
  135.     if (!installAEHandlers())
  136.         ExitToShell();
  137. }                /* end of initApp() */
  138.  
  139.  
  140.  
  141. /*****  checkGestaltFeatures() *****/
  142. Boolean checkGestaltFeatures()
  143. {
  144.     long        gestaltFeature;
  145.     OSErr        myErr;
  146.  
  147.     myErr = Gestalt(gestaltSystemVersion, &gestaltFeature);     /* which SysVersion present? */
  148.     if (myErr == noErr)
  149.     {
  150.         gestaltFeature = (gestaltFeature >> 8) & 0xf; 
  151.                                         /* shift result over & mask out major version number */
  152.         if (gestaltFeature < 7)         /* This is a System 7+ shell.  We quit otherwise. */
  153.         {
  154.             StopAlert(BADSYSTEMID, nil);
  155.             return(false);
  156.         }
  157.     }
  158.     
  159.     if (myErr == noErr)
  160.     {
  161.         myErr = Gestalt(gestaltQuickdrawVersion, &gestaltFeature);
  162.                                                     /* we want color QD cuz we're spoiled */
  163.         if (myErr == noErr)
  164.         {
  165.             if(gestaltFeature < gestalt32BitQD)
  166.             {
  167.                 StopAlert(BADQUICKDRAWID, nil);
  168.                 return(false);
  169.             }
  170.         }
  171.     }
  172.     
  173.     
  174.     
  175.     if (myErr == noErr)
  176.     {
  177.         myErr = Gestalt(gestaltAppleEventsAttr, &gestaltFeature);
  178.         if (myErr == noErr)
  179.         {
  180.             if (!(gestaltFeature & 0xf))
  181.             {
  182.                 StopAlert(NOAPPLEEVENTS, nil);
  183.                 return(false);
  184.             }
  185.         }
  186.     }
  187.     if (!myErr)        
  188.         return(true);            /* if there was an error we cannot continue */
  189.     else
  190.         return(false);            /* we made it through without a hitch */
  191. }
  192.  
  193. /*****    installAEHandlers *****/
  194. Boolean installAEHandlers()
  195. {
  196.     OSErr        myErr;
  197.     
  198.     myErr = AEInstallEventHandler ( kCoreEventClass, 
  199.                     kAEOpenApplication, NewAEEventHandlerProc(DoOpenAppAE), 0L, false );
  200.     if (myErr == noErr)
  201.         myErr = AEInstallEventHandler ( kCoreEventClass,
  202.                     kAEOpenDocuments, NewAEEventHandlerProc(DoOpenDocAE), 0L, false );
  203.     if (myErr == noErr)
  204.         myErr = AEInstallEventHandler ( kCoreEventClass,
  205.                     kAEPrintDocuments, NewAEEventHandlerProc(DoPrintDocAE), 0L, false );
  206.     if (myErr == noErr)
  207.         myErr = AEInstallEventHandler ( kCoreEventClass,
  208.                     kAEQuitApplication, NewAEEventHandlerProc(DoQuitAppAE), 0L, false );
  209.     if (myErr)
  210.         return(false);
  211.     else
  212.         return(true);
  213. }
  214.  
  215. /*****    setUpMenus() 
  216.             This will put up our menus.  Be sure to read the comments by the
  217.             AppendMenu() and SetItem() calls to see how different options
  218.             behave.        
  219. *****/
  220. void setUpMenus()
  221. {
  222.     short            n;
  223.     MenuHandle        theMenu;
  224.     
  225.     for (n = 0; n < MAXMENUS; n++)
  226.     {
  227.         theMenu = GetMenu(FIRSTMENUID + n);
  228.         if (theMenu)                  
  229.             InsertMenu(theMenu, 0);
  230.     }
  231.  
  232.     theMenu = GetMHandle(APPLEMENU);
  233.     if (theMenu)
  234.         AddResMenu(theMenu, 'DRVR');
  235.     
  236.     DrawMenuBar();
  237.     return;
  238. }                    /* end of setUpMenus()  */
  239.  
  240. /*****    setUpWindow() *****/
  241.  
  242. void setUpWindow( void )
  243. {
  244. #define        GLOBALWINDID    2001
  245.  
  246.     WindowPtr    myWind;
  247.  
  248.     myWind = GetNewCWindow(WINDOWID, nil, PUTINFRONT);
  249.     if (myWind != nil)
  250.     {
  251.         ShowWindow(myWind);
  252.         gIsShellWindVisible = true;
  253.     }
  254.     gStatusWindow = GetNewWindow(GLOBALWINDID, nil, PUTINFRONT);
  255.     if (gStatusWindow == nil)
  256.         DebugStr("\pWe can't put up StatusWindow.");
  257.     
  258.     SelectWindow(myWind);        // activate the "Shell Window"
  259. }
  260.  
  261.  
  262. /*****    doMousedown()
  263.             We figure out where the user has clicked the mouse.  If the user
  264.             clicks anywhere but the menu bar, we beep.  Otherwise, we figure
  265.             out which menu they have clicked and dispatch.
  266. *****/
  267. void doMousedown(EventRecord *eventRec)
  268. {
  269.     short        windPart;
  270.     WindowPtr    myWind;
  271.     long        menuResult;
  272.     
  273.     windPart = FindWindow(eventRec->where, &myWind);
  274.     
  275.     switch(windPart)
  276.     {
  277.         case inContent:
  278.             SelectWindow(myWind);
  279.             break;
  280.  
  281.         case inDrag:
  282.             DragWindow( myWind, eventRec->where, &qd.screenBits.bounds );
  283.             break;
  284.  
  285.         case inMenuBar:
  286.             menuResult = MenuSelect(eventRec->where);
  287.             dispatch(menuResult);
  288.             break;
  289.  
  290.         case inSysWindow:
  291.             SystemClick( eventRec, myWind );
  292.             break;
  293.             
  294.         case inGoAway:
  295.             gQuitTheApp = true;
  296.             break;
  297.             
  298.         default:
  299.             break;
  300.     }
  301.     return;
  302. }                 /* end of doMousedown */
  303.  
  304.  
  305. /*****     doKey()
  306.             We ignore keys pressed unless they are accompanied by a 
  307.             command key.  Then we dispatch.
  308. *****/
  309. void doKey(EventRecord *eventRec)
  310. {
  311.     char    keyPressed;
  312.     long    menuResult;
  313.     
  314.     keyPressed = (char) (eventRec->message & charCodeMask);
  315.     
  316.     if((eventRec->modifiers & cmdKey) != 0)
  317.     {
  318.         menuResult = MenuKey(keyPressed);
  319.         dispatch(menuResult);    
  320.     }
  321.     return;
  322. }                 /* end of do_key */
  323.  
  324.  
  325. /*****    doHighLevel() *****/
  326. void doHighLevel(EventRecord *eventRec)
  327. {
  328.     OSErr myErr;
  329.     myErr = AEProcessAppleEvent(eventRec);
  330. }
  331.  
  332.  
  333. pascal OSErr    DoOpenAppAE(AppleEvent theAppleEvent, AppleEvent reply, long refCon)
  334. {
  335.     setUpWindow();
  336.     return(noErr);
  337. }
  338. pascal OSErr    DoOpenDocAE(AppleEvent theAppleEvent, AppleEvent reply, long refCon)
  339. {
  340.     return(noErr);
  341. }
  342. pascal OSErr    DoPrintDocAE(AppleEvent theAppleEvent, AppleEvent reply, long refCon)
  343. {
  344.     return(noErr);
  345. }
  346. pascal OSErr    DoQuitAppAE(AppleEvent theAppleEvent, AppleEvent reply, long refCon)
  347. {
  348.     gQuitTheApp = true;
  349.     return(noErr);
  350. }
  351.  
  352.  
  353. /***** doUpdate() *****/
  354. void    doUpdate(EventRecord *eventRec)
  355. {
  356.     GrafPtr        savedPort;
  357.     WindowPtr    theWindow;
  358.     theWindow = (WindowPtr) eventRec->message;
  359.     
  360.     GetPort(&savedPort);
  361.     SetPort((GrafPtr) theWindow);
  362.     BeginUpdate(theWindow);
  363.     EndUpdate(theWindow);
  364.     SetPort(savedPort);
  365. }
  366.  
  367.  
  368. /*****     dispatch()
  369.             We determine which menu the user has chosen (either with mouse
  370.             or with command keys) and jump to the routine that handles
  371.             that menu's commands.
  372. *****/
  373. void dispatch(long menuResult)
  374. {
  375.     short        theMenu;            /* menu selected */
  376.     short        theItem;            /* item selected */
  377.     
  378.     theMenu = HiWord (menuResult);        /* menuID selected */
  379.     theItem = LoWord (menuResult);        /* item# selected */
  380.     
  381.     switch (theMenu)
  382.     {
  383.         case APPLEMENU:
  384.             doAppleCmds(theItem);
  385.             break;
  386.  
  387.         case FILEMENU:
  388.             doFileCmds(theItem);
  389.             break;
  390.             
  391.         case EDITMENU:
  392.             break;
  393.  
  394.         case TESTMENU:
  395.             doTestCmds(theItem);
  396.             break;
  397.     }
  398.     HiliteMenu(0);
  399. }                /* end of dispatch */
  400.  
  401.  
  402.  
  403. /*****     doAppleCmds() 
  404.             When the user chooses the "About MyMenuText" item, we display the
  405.             About box.  If the user chooses a DA, we open the DA.
  406. *****/
  407. void doAppleCmds(short theItem)
  408. {    
  409.     MenuHandle        myMenu;
  410.     Str255            name;
  411.     short            dummy;
  412.     
  413.     if(theItem == appleABOUT)
  414.     {
  415.         Alert(ABOUTID, (ModalFilterUPP) NIL);
  416.     }
  417.     else
  418.     {
  419.         myMenu = GetMHandle (APPLEMENU);
  420.         if (myMenu)
  421.         {
  422.             GetItem(myMenu, theItem, name);
  423.             dummy = OpenDeskAcc(name);
  424.         }
  425.     }
  426.     return;
  427. }                 /* end of doAppleCmds */
  428.  
  429.  
  430.  
  431. /*****    doFileCmds() 
  432.             When the user chooses Quit on the File menu, we quit.
  433. *****/
  434. void doFileCmds (short theItem)
  435. {
  436.     switch (theItem)
  437.     {            
  438.         case fileQUIT:
  439.             gQuitTheApp = true;
  440.             break;
  441.     }
  442.     return;
  443. } /* end of doFileCmds */
  444.  
  445.  
  446.  
  447. /*****    doTestCmds()
  448.             When the user chooses any of the items in the Test menu.  
  449.             They will see the TESTALERT. 
  450. *****/
  451. void doTestCmds (short theItem)
  452. {    
  453.  
  454.     switch (theItem)
  455.     {
  456.         case testWINDSHADE:
  457.             TestForWindowShade();
  458.             break;
  459.         case testHIDEWIND:
  460.             HideShellWindow();
  461.             break;
  462.         case testREVEALWIND:
  463.             RevealShellWindow();
  464.             break;
  465.     }    
  466.     return;
  467. }                /* end of doTestCmds */
  468.  
  469.  
  470.  
  471. void TestForWindowShade()
  472. {
  473.     WindowPtr    myShellWindow;
  474.     GrafPtr        oldPort;
  475.     Str255        theString;
  476.     short        windDimensions;
  477.     Point        globalWindPosition;
  478.     
  479.     myShellWindow = FrontWindow();        /* 
  480.                                             Unless you click in the StatusWindow, your
  481.                                             front window should be the Shell Window.
  482.                                         */
  483.     if (myShellWindow)        // if myShellWindow is not nil
  484.     {
  485.         if (myShellWindow != gStatusWindow)    // Make sure we're looking at Shell Window
  486.         {
  487.             GetPort(&oldPort);
  488.             SetPort(gStatusWindow);
  489.                 EraseRect(&gStatusWindow->portRect);
  490.                 MoveTo(10, 20);
  491.                 DrawString("\pShell Window's dimensions:");
  492.                 MoveTo(70, 40);
  493.                 DrawString("\pWidth = ");
  494.                 MoveTo(150, 40);
  495.                 windDimensions = (*myShellWindow).portRect.right - 
  496.                             (*myShellWindow).portRect.left;
  497.                 NumToString((long) windDimensions, theString);
  498.                 DrawString(theString);
  499.                 MoveTo(70, 60);
  500.                 DrawString("\pHeight = ");
  501.                 MoveTo(150, 60);
  502.                 windDimensions = (*myShellWindow).portRect.bottom - 
  503.                             (*myShellWindow).portRect.top;
  504.                 NumToString((long) windDimensions, theString);
  505.                 DrawString(theString);
  506.                 
  507.                 MoveTo(10, 80);
  508.                 DrawString ("\pThe global top and left of content region are:");
  509.                 
  510.                 MoveTo(70, 100);
  511.                 DrawString("\pGlobal Top = ");
  512.                 
  513.                 MoveTo(150, 100);
  514.                 globalWindPosition.v = (**((WindowPeek)myShellWindow)->contRgn).rgnBBox.top;
  515.                 NumToString((long) globalWindPosition.v, theString);
  516.                 DrawString(theString);
  517.                 
  518.                 MoveTo(70, 120);
  519.                 DrawString("\pGlobal Left = ");
  520.                 
  521.                 MoveTo(150, 120);
  522.                 globalWindPosition.h = (**((WindowPeek)myShellWindow)->contRgn).rgnBBox.left;
  523.                 NumToString((long) globalWindPosition.h, theString);
  524.                 DrawString(theString);
  525.                 
  526.                 MoveTo(10, 140);
  527.                 
  528.                 /*
  529.                     The next section of code tests to see if myShellWindow's
  530.                     contRgn is EMPTY. If it is, that means that WindowShade 
  531.                     has rolled up the content region.
  532.                     Note:  the window's portRect dimensions do not change.
  533.                 */
  534.                 
  535.                 if (EmptyRgn(((WindowPeek) myShellWindow)->contRgn))
  536.                     DrawString("\pShell Window has been rolled up.  Unshade it and retest.");
  537.                 else
  538.                     DrawString("\pShell Window unrolled. Shade the Shell Window & retest.");
  539.             SetPort(oldPort);
  540.         }
  541.         else        /*
  542.                         The status window is the front window.
  543.                         We don't test for shading there.  Tell user
  544.                         to activate the Shell window.
  545.                     */
  546.         {
  547.             GetPort(&oldPort);
  548.             SetPort(gStatusWindow);
  549.                 EraseRect(&gStatusWindow->portRect);
  550.                 MoveTo(10, 20);
  551.                 DrawString("\pWrong window is active. Click in Shell Window & retest.");
  552.             SetPort(oldPort);
  553.         }
  554.     }
  555.     
  556.  
  557. }
  558.  
  559. void HideShellWindow()
  560. {
  561.     WindowPtr    theShellWind;
  562.     GrafPtr        oldPort;
  563.     
  564.     
  565.     if (gIsShellWindVisible)
  566.     {
  567.         theShellWind = FrontWindow();
  568.         if (theShellWind != gStatusWindow)
  569.         {
  570.             gHiddenWindow = theShellWind;
  571.             myWindDimAndPos.windPort.left = (*theShellWind).portRect.left;
  572.             myWindDimAndPos.windPort.top = (*theShellWind).portRect.top;
  573.             myWindDimAndPos.windPort.right = (*theShellWind).portRect.right;
  574.             myWindDimAndPos.windPort.bottom = (*theShellWind).portRect.bottom;
  575.             
  576.             
  577.             // get the content rgn's global top and left coordinates
  578.             myWindDimAndPos.windPosition.h = (**(*(WindowPeek)theShellWind).contRgn).rgnBBox.left;
  579.             myWindDimAndPos.windPosition.v = (**(*(WindowPeek)theShellWind).contRgn).rgnBBox.top;
  580.                             
  581.             HideWindow(theShellWind);
  582.             gIsShellWindVisible = false;
  583.         }
  584.         else
  585.         {
  586.             GetPort(&oldPort);
  587.             SetPort(gStatusWindow);
  588.                 EraseRect(&gStatusWindow->portRect);
  589.                 MoveTo(10, 20);
  590.                 DrawString("\pWhy would you want to hide Status window?");
  591.             SetPort(oldPort);
  592.         }
  593.     }
  594.     else
  595.     {
  596.         GetPort(&oldPort);
  597.         SetPort(gStatusWindow);
  598.             EraseRect(&gStatusWindow->portRect);
  599.             MoveTo(10, 20);
  600.             DrawString("\pShell Window is hidden. Try revealing it instead.");
  601.         SetPort(oldPort);
  602.     }
  603. }
  604.  
  605. void RevealShellWindow()
  606. {
  607.     GrafPtr        oldPort;
  608.     
  609.     if (!gIsShellWindVisible)
  610.     {
  611.         if (gHiddenWindow != nil)
  612.         {
  613.             ShowWindow(gHiddenWindow);
  614.             SelectWindow(gHiddenWindow);
  615.             
  616.             gIsShellWindVisible = true;
  617.         }
  618.         else
  619.         {
  620.             GetPort(&oldPort);
  621.             SetPort(gStatusWindow);
  622.                 EraseRect(&gStatusWindow->portRect);
  623.                 MoveTo(10, 20);
  624.                 DrawString("\pProblems have emerged.  Quit while you're behind.");
  625.             SetPort(oldPort);
  626.         }
  627.     }
  628.     else
  629.     {
  630.         GetPort(&oldPort);
  631.         SetPort(gStatusWindow);
  632.             EraseRect(&gStatusWindow->portRect);
  633.             MoveTo(10, 20);
  634.             DrawString("\pShell window is visible.  Try hiding it first.");
  635.         SetPort(oldPort);
  636.     }
  637.  
  638. }